#ifndef _Matrix_included_
#define _Matrix_included_

#include "common.h"

#include "MatrixMath.h"

class MatrixMath;

class Matrix{
	public:
		Matrix();
		Matrix(string);
		Matrix(UINTN,UINTN,short);
		Matrix(UINTN,UINTN,short,short);
		Matrix(UINTN,UINTN,REALN*,short);
		Matrix(Matrix*,short);
		~Matrix();
		void save(string);
		void setUni(REALN);
		void setGrow(REALN,REALN);
		UINTN getRow();
		UINTN getCol();
		inline REALN get(UINTN i,UINTN j){
			if(memory==DEVICE_MEM){
				cout<<"Invalid access to device mem"<<endl;
				exit(3);
			}
			if(mode=='n'){
				return data[i*col+j];
			}else{
				return data[j*row+i];
			}
		}
		inline void set(REALN v,UINTN i,UINTN j){
			if(memory==DEVICE_MEM){
				cout<<"Invalid access to device mem"<<endl;
				exit(3);
			}
			if(mode=='n'){
				data[i*col+j]=v;
			}else{
				data[j*row+i]=v;
			}
		}
		void print();
		void print(UINTN);
		void printInfo();
		void printInfo(string);
		void printRaw(UINTN);
		UINTN getNData();
		UINTN getESize();
		UINTN getSize();
		REALN* getData();
		void transpose();
		void swapdim();
		char getMode();
		void setMode(char);
		short getMemorySpace();
		UINTN getLeading();
		REALN operator%(Matrix&);
		bool operator==(Matrix&);
		bool operator!=(Matrix&);
		void append(Matrix*,UINTN,UINTN);
		static void fast_compare(string,string,REALN,REALN);
	private:
		UINTN row;
		UINTN col;
		REALN* data;
		UINTN ndata;
		UINTN esize;
		UINTN size;
		char mode;
		short memory;
		bool ext_memory;
};

#endif
